﻿using HardcoreGame.Content.Items.Weapons.Sets.Sleep;
using HardcoreGame.Content.Projectiles.Others;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using ReLogic.Graphics;
using System.Linq;
using Terraria;
using Terraria.DataStructures;
using Terraria.GameContent;
using Terraria.Localization;
using Terraria.ModLoader;
using Terraria.ModLoader.IO;

namespace HardcoreGame.Common.Players
{
    public class SleepPlayer : ModPlayer
    {
        private int activeDreamProjectileID = -1;
        public int deathCountdown = -1;
        public int SleepTimer;
        public int StageForSleep = 1;
        private bool isShowingZzz = false;
        private Vector2 zzzPosition;
        private float zzzScale = 0f;
        private float zzzAlpha = 0f;
        private int zzzTimer = 0;
        private int zzzCycle = 0;
        private readonly Vector2[] zzzOffsetsRight = [
            new Vector2(-35, -10),
            new Vector2(-35, -10),
            new Vector2(-35, -10)
        ];

        private readonly Vector2[] zzzOffsetsLeft = [
            new Vector2(35, -10),
            new Vector2(35, -10),
            new Vector2(35, -10)
        ];

        public override void PostUpdate()
        {
            Player player = Main.player[Main.myPlayer];
            if (!player.sleeping.isSleeping)
            {
                isShowingZzz = false;
                zzzTimer = 0;
                zzzCycle = 0;
            }
            if (StageForSleep > 8)
            {
                StageForSleep = 8;
            }

            if (player.creativeGodMode)
            {
                StageForSleep = 1;
            }
            if (!player.sleeping.isSleeping)
            {
                SleepTimer++;
                if (SleepTimer >= 5 * 3600)
                {
                    if (StageForSleep < 8)
                    {
                        StageForSleep++;
                    }
                    SleepTimer = 0;
                }
                SleepTimer = 0;
                activeDreamProjectileID = -1;
            }
            else if (player.sleeping.isSleeping)
            {
                isShowingZzz = true;
                SleepTimer++;
                if (SleepTimer >= 3600)
                {
                    if (StageForSleep < 8)
                    {
                        StageForSleep--;
                    }
                    SleepTimer = 0;
                }
                bool hasBlockingItem = HasBlockingItem(player);
                bool dreamProjectileExists = activeDreamProjectileID >= 0 &&
                                     activeDreamProjectileID < Main.maxProjectiles &&
                                     Main.projectile[activeDreamProjectileID].active &&
                                     Main.projectile[activeDreamProjectileID].type == ModContent.ProjectileType<DreamItem>();
                if (!hasBlockingItem && !dreamProjectileExists && SleepTimer % 900 == 0 && Main.rand.NextBool(5))
                {
                    int projectileID = Projectile.NewProjectile(
                        player.GetSource_FromAI(),
                        player.Center + new Vector2(0, -60),
                        Vector2.Zero,
                        ModContent.ProjectileType<DreamItem>(),
                        0,
                        0,
                        player.whoAmI
                    );
                    if (projectileID >= 0 && projectileID < Main.maxProjectiles)
                    {
                        activeDreamProjectileID = projectileID;
                    }
                }
                UpdateZzzEffect(player);
            }
            if (StageForSleep == 8)
            {
                if (deathCountdown == -1)
                {
                    deathCountdown = 10 * 60;
                    Main.NewText(Language.GetTextValue("Mods.HardcoreGame.PlayerDeathReason.2"), 255, 0, 0);
                }
                else
                {
                    deathCountdown--;
                    if (deathCountdown <= 0)
                    {
                        player.KillMe(PlayerDeathReason.ByCustomReason(NetworkText.FromKey("Mods.HardcoreGame.PlayerDeathReason.1", player.name)), player.statLifeMax2, 0);
                        deathCountdown = -1;
                    }
                }
            }
            else
            {
                if (deathCountdown != -1)
                {
                    deathCountdown = -1;
                }
            }
        }

        private void UpdateZzzEffect(Player player)
        {
            zzzTimer++;

            if (zzzTimer >= 100)
            {
                zzzTimer = 0;
                zzzCycle = (zzzCycle + 1) % 3;

                float headOffsetY = -player.height * 0.4f;
                Vector2[] currentOffsets = player.direction == 1 ? zzzOffsetsRight : zzzOffsetsLeft;

                zzzPosition = player.Center + new Vector2(0, headOffsetY) + currentOffsets[zzzCycle];
                zzzScale = 0.5f;
                zzzAlpha = 1f;
            }

            if (zzzTimer < 30)
            {
                zzzScale = 0.5f + zzzTimer / 30f * 0.7f;
                zzzPosition.Y -= 0.5f;
                zzzPosition.X += -player.direction * 0.3f;
            }
            else if (zzzTimer < 70)
            {
                zzzPosition.Y -= 1.2f;
                zzzPosition.X += -player.direction * 0.8f;
            }
            else
            {
                zzzAlpha = 1f - ((zzzTimer - 70) / 30f);
                zzzPosition.Y -= 0.9f;
                zzzPosition.X += -player.direction * 0.6f;
            }
        }

        public override void DrawEffects(PlayerDrawSet drawInfo, ref float r, ref float g, ref float b, ref float a, ref bool fullBright)
        {
            if (!isShowingZzz || drawInfo.shadow != 0f)
                return;

            Player player = Main.player[Main.myPlayer];
            if (player.whoAmI == Main.myPlayer)
            {
                string zzzText = "z";
                Color zzzColor = Color.White * zzzAlpha;
                Vector2 origin = FontAssets.MouseText.Value.MeasureString(zzzText) / 2f;

                Vector2 shadowPos = zzzPosition - Main.screenPosition + new Vector2(2f, 2f);
                Main.spriteBatch.DrawString(FontAssets.MouseText.Value, zzzText, shadowPos, Color.Black * zzzAlpha * 0.7f, 0f, origin, zzzScale, SpriteEffects.None, 0f);
                Main.spriteBatch.DrawString(FontAssets.MouseText.Value, zzzText, zzzPosition - Main.screenPosition, zzzColor, 0f, origin, zzzScale, SpriteEffects.None, 0f);
            }
        }

        public override void SaveData(TagCompound tag)
        {
            tag["StageForSleep"] = StageForSleep;
            tag["SleepTimer"] = SleepTimer;
        }

        public override void LoadData(TagCompound tag)
        {
            StageForSleep = tag.GetInt("StageForSleep");
            SleepTimer = tag.GetInt("SleepTimer");
        }

        public override void Kill(double damage, int hitDirection, bool pvp, PlayerDeathReason damageSource)
        {
            isShowingZzz = false;
            zzzTimer = 0;
            zzzCycle = 0;
            StageForSleep = 1;
            SleepTimer = 0;
        }
        private readonly int[] dreamBlockingItems = [ModContent.ItemType<DreamShuriken>()];
        private bool HasBlockingItem(Player player)
        {
            for (int i = 0; i < player.inventory.Length; i++)
            {
                Item item = player.inventory[i];
                if (item.active && dreamBlockingItems.Contains(item.type))
                {
                    return true;
                }
            }
            return false;
        }
    }
}